<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇</title>
    <link rel="stylesheet" href="../reset.css">
    <style>
        * {
            box-sizing: border-box;
        }

        #main {
            height: 420px;
            width: 360px;
            border: 10px #000 solid;
            background-color: #b7d4a8;
            border-radius: 20px;
            margin: 50px auto;
        }

        #stage {
            width: 304px;
            height: 304px;
            border: 2px #000 solid;
            margin: 20px auto;
            position: relative;
        }

        #snake>div {
            width: 10px;
            height: 10px;
            background-color: #000;
            position: absolute;
            border: 1px solid #b7d4a8;
        }

        #food {
            width: 10px;
            height: 10px;
            position: absolute;
            top: 100px;
            left: 100px;
            display: flex;
            flex-flow: row wrap;
        }

        #food>div {
            width: 5px;
            height: 5px;
            background-color: red;
            animation: blinker 0.75s ease-in-out infinite;
            transform: rotate(45deg);
        }

        @keyframes blinker {
            25% {
                opacity: 0.5;
            }
            50% {
                opacity: 0;
            }
            75% {
                opacity: 0.5;
            }
        }

        #info {
            width: 304px;
            margin: 0 auto;
            display: flex;
            justify-content: space-between;
            font: bold 20px courier;
        }
    </style>
    <script>

        /* 
            1.禁止掉头
            2.游戏终止
            3.记录分数
        
                游戏禁止掉头有两个构成要件
                    1.身体超过2
                    2.方向不能是相反方向。

                处理方式
                    保持原来的方向不变（不修改dir的值）


        */
        document.addEventListener("DOMContentLoaded", () => {

            // 获取蛇
            const snake = document.getElementById("snake")

            // 获取蛇的各个部分
            const snakes = snake.getElementsByTagName("div")

            // 获取食物
            const food = document.getElementById("food")

            // 获取计分板和等级
            const scoreSpan=document.getElementById("score")
            const levelSpan=document.getElementById("level")

            // 创建变量存储分数和等级
            let score=0
            let level=0


            // 食物的宽度范围在[0-290],这里一定要是[0-29]*10的数
            function changeFood() {
                const x = Math.floor(Math.random() * 30) * 10;
                const y = Math.floor(Math.random() * 30) * 10;

                // 设置食物的坐标
                food.style.left = x + "px"
                food.style.top = y + "px"

            }

            changeFood()

            // 定义一个变量用来存储蛇移动的方向

            let dir

            // 创建一个变量来记录按键的状态
            let keyActive = true

            const keyArr = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight",
                "w", "a", "s", "d",
                "W", "A", "S", "D"]

            const reObj = {
                ArrowUp: ["ArrowDown", "s", "S"],
                w: ["ArrowDown", "s", "S"],
                W: ["ArrowDown", "s", "S"],

                ArrowDown: ["Arrowup", "w", "W"],
                S: ["Arrowup", "w", "W"],
                s: ["Arrowup", "w", "W"],

                ArrowLeft: ["ArrowRight", "d", "D"],
                a: ["ArrowRight", "d", "D"],
                A: ["ArrowRight", "d", "D"],

                ArrowRight: ["ArrowLeft", "a", "A"],
                D: ["ArrowLeft", "a", "A"],
                d: ["ArrowLeft", "a", "A"],
            }

            document.addEventListener("keydown", (event) => {
                if (keyActive && keyArr.includes(event.key)) {
                    if (snakes.length < 2 || !reObj[dir].includes(event.key)) {
                        // 设置方向
                        dir = event.key
                        keyActive = false
                    }
                }
            })

            /* 
                要使得身体和头部一起移动时，只需要在蛇移动时，变换蛇尾部的位置。
            
            */

            let isGameOver = false

            setTimeout(function move() {
                keyActive=true

                // 获取蛇头
                const snakesHead = snakes[0]

                let x = snakesHead.offsetLeft
                let y = snakesHead.offsetTop

                switch (dir) {
                    case "ArrowUp":
                    case "w":
                    case "W":
                        // 向上移动蛇
                        y -= 10
                        break;

                    case "ArrowDown":
                    case "s":
                    case "S":
                        // 向下移动蛇
                        y += 10
                        break;

                    case "ArrowLeft":
                    case "a":
                    case "A":
                        // 向左移动蛇
                        x -= 10
                        break;

                    case "ArrowRight":
                    case "d":
                    case "D":
                        // 向右移动蛇
                        x += 10
                        break;
                }

                // 检查蛇是否吃到食物
                if (snakesHead.offsetTop === food.offsetTop && snakesHead.offsetLeft === food.offsetLeft) {
                    changeFood()
                    snake.insertAdjacentElement("beforeend", snakes[0].cloneNode(true))
                    // 吃到食物之后1.改变食物的位置，2.增加蛇的身体
                    // 食物的宽度范围在[0-290]
                    score++;
                    scoreSpan.textContent=score

                    // 检查等级
                    if(score%3===0&&level<10){
                        level++
                        levelSpan.textContent=level+1
                    }
                    else if(level===10){
                        alert(`您通关了，您的分数为${score}`)
                    }
                }
                /* 
                    判断游戏是否结束？1.撞墙2.撞自己
                */
                if (x < 0 || x > 290 || y<0 || y > 290) {
                    // 游戏结束（定时器关闭）
                    alert("撞墙了，游戏结束！")
                    return
                }

                // 判断是否撞到自己
                for (let i = 0;i<snakes.length-1;i++){
                    if(
                        snakes[i].offsetLeft===x && 
                        snakes[i].offsetTop===y
                    ){
                        alert("撞到自己了，游戏结束！")
                        return
                        }
                }

                // 获取尾巴
                const tail = snakes[snakes.length - 1]

                // 移动尾巴的位置
                tail.style.left = x + "px"
                tail.style.top = y + "px"

                // 将尾巴移动到蛇头位置
                snake.insertAdjacentElement("afterbegin", tail)
                keyActive = true

                setTimeout(move, 300-level*20)
            }, 300)

        })

    </script>
</head>

<body>
    <div id="main">
        <div id="stage">
            <div id="snake">
                <div></div>
            </div>
            <div id="food">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
        </div>
        <div id="info">
            <div>
                SCORE: <span id="score">0</span>
            </div>
            <div>
                LEVEl: <span id="level">1</span>
            </div>
        </div>
    </div>
</body>

</html>